﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Facebook;
using System.Net;
using System.Text.RegularExpressions;

namespace BazaartBI
{
    class FbUtils
    {
        private class PageExtraInfo
        {
            public IEnumerable<string> Emails { get; set; }
            public string PinterestUser { get; set; }
            public bool AreInNY { get; set; }
        }

        FacebookClient Client { get; set; }
        readonly string AccessToken = @"AAACqInQtSkcBAJi3gjczjNSSCflgoV19dZBl9T3dO8893buYQvHHjhpvu6nPL6Y4rA63wZAcIdSVEUghHof1x9DyFvYBwZD";
        public FbUtils()
        {
            Client = new FacebookClient(AccessToken);
        }


        public FacebookInfo GetPageInfo(string pId)
        {
            try
            {
                var query = string.Format("https://graph.facebook.com/{0}", pId);
                dynamic page = Client.Get(query);
                dynamic location = page.location;
                long likes = page.likes;
                string url = page.link;
                string name = page.name;

                var extraInfo = ParseHtmlForExtraInfo(url);
                return new FacebookInfo()
                {
                    Name = name,
                    PageUrl = url,
                    PageId = pId,
                    IsInNewYork = extraInfo.AreInNY,
                    PinterestUser = extraInfo.PinterestUser,
                    Emails = extraInfo.Emails,
                    Likes = likes
                };
            }
            catch
            {
                //TODO: Log error
                return new FacebookInfo();
            }
        }

        private PageExtraInfo ParseHtmlForExtraInfo(string url)
        {
            string infoTabUrl = string.Format("{0}?sk=info", url);
            using (var client = new WebClient())
            {
                client.Headers.Add("User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");
                var html = client.DownloadString(infoTabUrl);
                var replacedContent = html.Replace("&#064;", "@");
                var emails =  ExtractEmail(replacedContent);
                emails = emails.Distinct().ToList();
                var pinterestUser = FindPinterestUser(replacedContent);
                bool areNewYork = AreInNewYork(replacedContent);

                return new PageExtraInfo()
                {
                    Emails = emails,
                    AreInNY = areNewYork,
                    PinterestUser = pinterestUser
                };
            }
        }

        private bool AreInNewYork(string text)
        {
            var regex = "/$pinterest.com$";
            var rx = new Regex(regex, RegexOptions.Compiled | RegexOptions.IgnoreCase);
            // Find matches.
            var matches = rx.Matches(text);
            // Report on each match.
            return (from Match match in matches select match.Value).Any();
        }

        private string FindPinterestUser(string text)
        {
            var regex = "/$pinterest.com$";
            var rx = new Regex(regex, RegexOptions.Compiled | RegexOptions.IgnoreCase);
            // Find matches.
            var matches = rx.Matches(text);
            // Report on each match.
            return (from Match match in matches select match.Value).FirstOrDefault();
        }

        private List<string> ExtractEmail(string text)
        {
            //replacing strange characters that are usually appended to @ with empty spaces
            var emailText = text.Replace("", "");
            emailText = emailText.Replace("*", "");
            emailText = emailText.Replace("#", "");

            const string matchEmailPattern =
            @"(([\w-]+\.)+[\w-]+|([a-zA-Z]{1}|[\w-]{2,}))@"
            + @"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\."
            + @"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|"
            + @"([a-zA-Z]+[\w-]+\.)+[a-zA-Z]{2,4})";

            var rx = new Regex(matchEmailPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
            // Find matches.
            var matches = rx.Matches(emailText);
            // Report on each match.
            return (from Match match in matches select match.Value).ToList();
        }

        public string GetFbId(string businessName)
        {
            var query = string.Format("https://graph.facebook.com/search?q={0}&type=page", businessName.Replace("&", "and"));
            dynamic pages = Client.Get(query);
            if (pages.ContainsKey("error_code"))
                return string.Empty;

            foreach (dynamic record in pages.data)
            {
                if (record.category.ToLower().Contains("clothing") || record.category.ToLower().Contains("shopping") || record.category.ToLower().Contains("retail"))
                {
                    return record.id;
                }
            }
            return string.Empty;
        }
    }
}
